package org.gtesoreria

class ConsumoService {

    static transactional = true
	def dateUtilsService
	def getPorcSubsidio(){
		Configuracion conf = Configuracion.list().get(0)
		if(!conf)
			return 15
		return conf?.porcSubsidio;
	}
	
	def getConfiguracion(){
		Configuracion conf = Configuracion.list().get(0)
		return conf
	}

		
    def consumosSuper(Afiliado af, Date from, Date to) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", af)
			proveedor{ rubro{eq("codigo", Rubro.rubroSuper.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
    }
	
	
	def consumosVarios(Afiliado afiliado, Date from, Date to) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			proveedor{ rubro{eq("codigo", Rubro.rubroVarios.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosAuto(Afiliado afiliado, Date from, Date to) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			proveedor{ rubro{eq("codigo", Rubro.rubroAuto.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosInd(Afiliado afiliado, Date from, Date to) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			proveedor{ rubro{eq("codigo", Rubro.rubroInd.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosFarmacia(Afiliado afiliado, Date from, Date to) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha", from,to)
			eq("afiliado", afiliado)
			proveedor{ rubro{eq("codigo", Rubro.rubroFarmacia.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosPeriodo(Afiliado afiliado, Date period) {
		def cal = Calendar.instance
		cal.setTime(period)
		cal.set( Calendar.DAY_OF_MONTH, 1)
		Date from = cal.getTime();
		cal.add( Calendar.MONTH, 1);
		cal.set( Calendar.DAY_OF_MONTH, 1)
		Date to = cal.getTime();
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosEntreFechas(Afiliado afiliado, Date from, Date to) {

		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosEnProveedorEntreFechas(Proveedor proveedor, Date from, Date to, String anSort, String anOrder) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("proveedor", proveedor)
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else if(anSort && anOrder)
				order(anSort, anOrder)
			else
				order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosRubroEntreFechas(Rubro rubroConsulta, Date from, Date to, String estado) {
		
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("estado", estado)
			proveedor{ rubro{eq("codigo", rubroConsulta.codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def getSubTotal(List<Consumo> consumos){
		Double result = 0;
		for (Consumo consumo : consumos) {
			result += consumo.monto;
		}
		return result;
	}
	
	def getSubTotalSubsidio(List<ConsumoFarmacia> consumos){
		Double result = 0;
		for (Consumo consumo : consumos) {
			result += consumo.subsidio;
		}
		return result;
	}
	
	def getSubTotalACargoAfiliado(List<ConsumoFarmacia> consumos){
		Double result = 0;
		for (Consumo consumo : consumos) {
			result += consumo.aCargoAfiliado;
		}
		return result;
	}
	
	def getSubTotalDescuento(List<Consumo> consumos){
		Double result = 0;
		for (Consumo consumo : consumos) {
			result += consumo.montoDescuento();
		}
		return result;
	}
	
	def getSubTotalProveedor(List<Consumo> consumos){
		Double result = 0;
		for (Consumo consumo : consumos) {
			result += consumo.montoProveedor();
		}
		return result;
	}
	
	def consumosRubroEntreFechasGroupByAfiliado(Rubro rubroConsulta, Date from, Date to, String estado){
		def consumosRubro = consumosRubroEntreFechas(rubroConsulta, from, to, estado);
		def consumidores =[:]
		for (Consumo consumo : consumosRubro) {
			if(consumidores.get(consumo.afiliado) != null){
				Consumo copiaConsumo = consumidores.get(consumo.afiliado)
				Double monto = copiaConsumo.montoDescuento()
				copiaConsumo.monto += consumo.montoDescuento() 
				consumidores.put(consumo.afiliado, copiaConsumo)
			} else {
				def copiaConsumo = null
				if(consumo instanceof ConsumoFarmacia) {
					copiaConsumo = new ConsumoFarmacia(monto:consumo.monto,
						subsidio:consumo.subsidio,aCargoAfiliado:consumo.aCargoAfiliado,
						afiliado:consumo.afiliado,
						proveedor:consumo.proveedor,
						nroCuota:1, cantCuotas:1)
					copiaConsumo.monto = copiaConsumo.montoDescuento()
				} else {
					copiaConsumo = new Consumo(monto:consumo.monto,
						afiliado:consumo.afiliado,
						proveedor:consumo.proveedor,
						nroCuota:1, cantCuotas:1)
				}
				consumidores.put(consumo.afiliado, copiaConsumo)
			}
			
		}
		return consumidores.values().toList()
	}
	
	def consumosBetweenDates(Date from, Date to, String anSort, String anOrder, String offset,int max) {
		def query = Consumo.createCriteria()
		def consumosDe = query.list([offset:offset, max:max]) {
			between("fecha",  from, to)
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else{
				order(anSort, anOrder)
			}
		}
		return consumosDe
	}
	
	def consumosBetweenDates(Date from, Date to, String anSort, String anOrder) {
		def query = Consumo.createCriteria()
		def consumosDe = query.list() {
			between("fecha",  from, to)
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else if(anSort && anOrder)
				order(anSort, anOrder)
			else
				order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosBetweenDates(Date from, Date to, String anSort, String anOrder, String offset,int max, String estado) {
		def query = Consumo.createCriteria()
		def consumosDe = query.list([offset:offset, max:max]) {
			between("fecha",  from, to)
			eq("estado", estado)
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else{
				order(anSort, anOrder)
			}
		}
		return consumosDe
	}
	
	def consumosBetweenDatesNoSort(Date from, Date to) {
		def query = Consumo.createCriteria()
		def consumosDe = query{
			between("fecha",  from, to)
			order("fecha", "desc")
		}
		return consumosDe
	}
	
	def subsidiosEnProveedorEntreFechas(Proveedor pro, Date from, Date to, String anSort, String anOrder){
		def query = Consumo.createCriteria()
		def consumosDe = query{
			eq("proveedor", pro)
			between("fecha",  from, to)
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else if(anSort && anOrder)
				order(anSort, anOrder)
			else
				order("fecha","asc")
		}
		return consumosDe
	}
	
	def subsidiosEntreFechas(Date from, Date to, String anSort, String anOrder) {
		def query = Consumo.createCriteria()
		def consumosDe = query{
			proveedor{ rubro{eq("codigo", Rubro.rubroFarmacia.codigo)}}
			between("fecha",  from, to)
			
			if(anSort == "afiliado.apellidoNombre"){
				afiliado{
					order("apellidoNombre", anOrder)
				}
			} else if(anSort && anOrder)
				order(anSort, anOrder)
			else
				order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosPorPeriodoPorRubro(Afiliado afiliado,Date from, String codigo) {
		Date to = dateUtilsService.getFirstDayOfTheNextMonth(from)
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			proveedor{ rubro{eq("codigo", codigo)}}
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosPorPeriodo(Afiliado afiliado,Date from) {
		Date to = dateUtilsService.getFirstDayOfTheNextMonth(from)
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def consumosBetweenDates(Afiliado afiliado,Date from, Date to) {
		def query = Consumo.createCriteria()
		def consumosDe = query {
			between("fecha",  from, to)
			eq("afiliado", afiliado)
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def afiliadosConConsumosEnEstado(String estado) {
		def query = Consumo.createCriteria()
		def consumosDe = query.listDistinct() {
			eq("estado", estado)
			order("fecha","asc")
			projections {
				property("afiliado")
			}
		}
		return consumosDe
	}
	
	def consumosEnEstado(Afiliado afiliado, String codigoRubro, String estado) {
		def query = Consumo.createCriteria()
		def consumosDe = query.listDistinct() {
			eq("estado", estado)
			proveedor{ rubro{eq("codigo", codigoRubro)}}
			eq("afiliado", afiliado)
			order("fecha","asc")
		}
		return consumosDe
	}
	
	def updateEstado(List consumos, String nuevoEstado){
		for(Consumo c in consumos){
			c.estado = nuevoEstado;
			c.save(flush:true)
		}
	}
}
